#include "config.h"

#include "libbase.h"

extern char	*runtest_home;

static void
build_folders(void)
{
	ecm_mkdir("bin", ECM_P_ALLU);
	ecm_mkdir("etc", ECM_P_ALLU);
	ecm_mkdir("ecx", ECM_P_ALLU);
	ecm_mkdir("rc", ECM_P_ALLU);
	ecm_mkdir("modules", ECM_P_ALLU);
	ecm_mkdir("log", ECM_P_ALLU);
}

static ECMBOOL
copy_file(const char *src, const char *dstdir)
{
	char	buf[4096];
	char	*dst;
	int	fd_src, fd_dst;

	fd_src = ecm_open(src, ECM_O_RDONLY);
	if (fd_src < 0)
		return ECM_FALSE;
	dst = ecm_gen_rpath(dstdir, ecm_basename(src));
	fd_dst = ecm_open(dst, ECM_O_WRONLY | ECM_O_TRUNC | ECM_O_CREAT, ECM_P_ALLU);
	if (fd_dst < 0) {
		ecm_close(fd_src);
		ecm_free(dst);
		return ECM_FALSE;
	}
	ecm_free(dst);

	while (ECM_TRUE) {
		ecm_size_t	size;

		size = 4096;
		if (!ecm_read(fd_src, buf, &size) || size == 0)
			break;
		if (!ecm_write(fd_dst, buf, &size))
			break;
	}
	ecm_close(fd_src);
	ecm_close(fd_dst);

	return ECM_TRUE;
}

static void
copy_binary(const char *clxhome, const char *src_relpath, const char *dst_dirname)
{
	char	*dstdir_path;
	char	*src;

	dstdir_path = ecm_gen_rpath(clxhome, dst_dirname);

	src = ecm_gen_rpath(runtest_home, src_relpath);
	if (!copy_file(src, dstdir_path))
		ecm_test_failed("cannot copy %s", ecm_basename(src_relpath));

	ecm_free(src);
	ecm_free(dstdir_path);
}

static void
copy_programs(const char *clxhome)
{
#ifndef _WIN32
	const char	*bin_srcs[] = {
		"../src/ebcd/ebcd",
		"../src/edbd/edbd",
		"../src/ecx/egid",
		"../src/ecmconf/ecmconf",
		NULL
	};
	const char	*rc_srcs[] = {
		"snapshot.init",
		NULL
	};
	const char	*modules_srcs[] = {
		"test.smod",
		".libs/test.so",
		NULL
	};
	const char	*etc_srcs[] = {
		"license.key",
		NULL
	};
#else
	const char	*bin_srcs[] = {
		"ebcd.exe",
		"edbd.exe",
		"egid.exe",
		"ecmconf.exe",
		NULL
	};
	const char	*rc_srcs[] = {
		"snapshot.init",
		NULL
	};
	const char	*modules_srcs[] = {
		"test.smod",
		"test.dll",
		NULL
	};
	const char	*etc_srcs[] = {
		"..\\..\\test\\license.key",
		NULL
	};
#endif
	int	i;

	for (i = 0; bin_srcs[i]; i++)
		copy_binary(clxhome, bin_srcs[i], "bin");

	for (i = 0; rc_srcs[i]; i++)
		copy_binary(clxhome, rc_srcs[i], "rc");

	for (i = 0; modules_srcs[i]; i++)
		copy_binary(clxhome, modules_srcs[i], "modules");

	for (i = 0; etc_srcs[i]; i++)
		copy_binary(clxhome, etc_srcs[i], "etc");
}

void
build_clxhome(const char *clxhome)
{
	char	cwd_org[1024];

	if (ecm_getcwd(cwd_org, 1024) != ECM_OK)
		ecm_test_failed("cannot get current working directory");

	if (ecm_chdir(clxhome) == ECM_OK) {
		ecm_chdir(cwd_org);
		return;
	}

	if (ecm_mkdir(clxhome, ECM_P_ALLU) != ECM_OK)
		ecm_test_failed("%s: cannot create", clxhome);

	if (ecm_chdir(clxhome) != ECM_OK)
		ecm_test_failed("%s: cannot change CLX_HOME", clxhome);

	build_folders();

	copy_programs(clxhome);

	ecm_chdir(cwd_org);
}
